package org.dt.common.sequence;

import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.Executor;

import org.dt.common.sequence.config.SeqHolderSpec;

@Slf4j
public abstract class AbstractSequenceHolder implements SequenceHolder {

    protected final String biz;
    protected final long   capacity;
    protected final float  loadFactor;

    protected BaseDelegator delegator;
    protected Executor      taskExecutor;

    private volatile boolean initiated = false;

    AbstractSequenceHolder(String biz, SeqHolderSpec config, BaseDelegator delegator, Executor taskExecutor) {
        this.biz        = biz;
        this.capacity   = config.getCapacity();
        this.loadFactor = config.getLoadFactor();

        this.delegator    = delegator;
        this.taskExecutor = taskExecutor;
    }

    @Override
    public List<Sequence> applyFor(Long need) {
        if (!initiated) {
            synchronized (this) {
                if (!initiated) {
                    log.debug("start initialization for {}", biz);
                    init();
                    initiated = true;
                }
            }
        }
        return doApplyFor(need);
    }

    /**
     * actual applyFor
     *
     * @param need serial number count
     * @return sequence
     */
    protected abstract List<Sequence> doApplyFor(Long need);

    /**
     * init method
     */
    protected abstract void init();
}